﻿using DimensionsHelper.Common.Utils.Converters;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Json.Serialization.Metadata;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Text.Unicode;
using System;

namespace DimensionsHelper.Common.Utils;

public static class JsonHelper
{

    private static JsonSerializerOptions GetJsonSerializerOptions(IJsonTypeInfoResolver? resolver = null)
    {
        return new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
            WriteIndented = true,
            AllowTrailingCommas = true,
            IgnoreReadOnlyFields = true,
            IgnoreReadOnlyProperties = true,
            PropertyNameCaseInsensitive = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
            TypeInfoResolver = resolver,
            Converters =
            {
                new ColorJsonConverter(),
                new ExcelStyleColorJsonConverter(),
                new JsonStringEnumConverter()
            }
        };
    }


    public static string Serialize(object data, IJsonTypeInfoResolver? resolver = null)
    {
        return JsonSerializer.Serialize(data, GetJsonSerializerOptions(resolver));
    }


    public static string Serialize<T>(T data, JsonTypeInfo<T> jsonTypeInfo)
    {
        return JsonSerializer.Serialize(data, jsonTypeInfo);
    }


    public static T? Deserialize<T>(string json, IJsonTypeInfoResolver? resolver = null)
    {
        return JsonSerializer.Deserialize<T>(json, GetJsonSerializerOptions(resolver));
    }


    public static T? Deserialize<T>(string json, JsonTypeInfo<T> jsonTypeInfo)
    {
        return JsonSerializer.Deserialize(json, jsonTypeInfo);
    }


    public static T? ReadJson<T>(string jsonFileName, IJsonTypeInfoResolver? resolver = null)
    {
        using FileStream stream = File.OpenRead(jsonFileName);
        return JsonSerializer.Deserialize<T>(stream, GetJsonSerializerOptions(resolver));
    }


    public static T? ReadJson<T>(string jsonFileName, JsonTypeInfo<T> jsonTypeInfo)
    {
        using FileStream stream = File.OpenRead(jsonFileName);
        return JsonSerializer.Deserialize(stream, jsonTypeInfo);
    }


    public static T? ReadJson<T>(byte[] bytes, JsonTypeInfo<T> jsonTypeInfo)
    {
        return JsonSerializer.Deserialize(bytes, jsonTypeInfo);
    }


    public static T? ReadJson<T>(ReadOnlySpan<char> chars, JsonTypeInfo<T> jsonTypeInfo)
    {
        return JsonSerializer.Deserialize(chars, jsonTypeInfo);
    }


    public static void WriteJson<T>(T obj, string outputFileName, IJsonTypeInfoResolver? resolver)
    {
        using FileStream stream = new(outputFileName, FileMode.Create, FileAccess.Write);
        JsonSerializer.Serialize(stream, obj, GetJsonSerializerOptions(resolver));
    }


    public static void WriteJson<T>(T obj, JsonTypeInfo<T> jsonTypeInfo, string outputFileName)
    {
        using FileStream stream = new(outputFileName, FileMode.Create, FileAccess.Write);
        JsonSerializer.Serialize(stream, obj, jsonTypeInfo);
    }


    public static void WriteJson(object obj, string outputFileName)
    {
        using FileStream stream = new(outputFileName, FileMode.Create, FileAccess.Write);
        JsonSerializer.Serialize(stream, obj, GetJsonSerializerOptions(ServiceJsonContext.Default));
    }

}
